package com.leo.foodmaster.admin.system.controller;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.google.code.kaptcha.Producer;
import com.leo.foodmaster.admin.system.entity.LoginBody;
import com.leo.foodmaster.admin.system.entity.Router;
import com.leo.foodmaster.admin.system.entity.UserBean;
import com.leo.foodmaster.admin.system.service.IPermissionService;
import com.leo.foodmaster.admin.system.service.IUserService;
import com.leo.foodmaster.commons.config.FoodMasterProperties;
import com.leo.foodmaster.commons.constants.AuthConstants;
import com.leo.foodmaster.commons.entity.Result;
import com.leo.foodmaster.commons.util.TokenUtils;
import com.leo.foodmaster.commons.util.WebUtils;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户授权认证前端控制器
 * </p>
 *
 * @author ：Leo
 * @since ：2021-06-18 16:11
 */
@RestController
@Api(tags = "授权认证管理")
@RequestMapping("/auth")
public class AuthController {
    @Resource
    private IUserService userService;
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;
    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private TokenUtils tokenUtils;
    @Resource
    private FoodMasterProperties foodMasterProperties;
    @Resource
    private IPermissionService permissionService;


    /**
     * 用户登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("login")
    @ApiOperation("用户登录")
    public Result<String> login(@RequestBody LoginBody loginBody) {
        // 生成令牌
        return Result.success(userService.login(loginBody.getUsername(), loginBody.getPassword(),
                loginBody.getCode(), loginBody.getCaptchaId()));
    }

    /**
     * 生成验证码
     */
    @GetMapping("captchaImage")
    @ApiOperation("获取验证码")
    public Result<Map<String, Object>> getCaptcha() throws IOException {
        // 保存验证码信息
        String captchaId = IdUtil.simpleUUID();
        String captchaKey = AuthConstants.CAPTCHA_CODE_KEY + captchaId;

        String capStr;
        String code;
        BufferedImage image;

        // 生成验证码
        if (foodMasterProperties.getCaptchaType().equals(AuthConstants.CAPTCHA_TYPE_MATH)) {
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        } else {
            capStr = code = captchaProducer.createText();
            image = captchaProducer.createImage(capStr);
        }
        redisTemplate.opsForValue().set(captchaKey, code, AuthConstants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);

        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        ImageIO.write(image, "jpg", os);

        Map<String, Object> map = new HashMap<>(2);
        map.put("captchaId", captchaId);
        map.put("img", Base64.encode(os.toByteArray()));
        return Result.success(map);
    }

    @GetMapping("loginUserInfo")
    @ApiOperation("获取登录用户信息")
    public Result<Map<String, Object>> getLoginUserInfo() {
        UserBean user = WebUtils.getUser();
        // 角色集合
        String[] roles = user.getRoles().split(StrUtil.COMMA);
        // 权限集合
        List<String> permissions = permissionService.getPermissionsByUserId(user.getId());
        Map<String, Object> map = new HashMap<>(3);
        map.put("user", user);
        map.put("roles", roles);
        map.put("permissions", permissions);
        return Result.success(map);
    }

    @ApiOperation("获取用户路由信息")
    @GetMapping("getRouters")
    public Result<List<Router>> getRouters() {
        Long userId = WebUtils.getUser().getId();
        List<Router> routerList = permissionService.getRoutersByUserId(userId);
        return Result.success(routerList);
    }

    @ApiOperation(value = "用户注销", notes = "logout")
    @PostMapping("logout")
    public Result<Void> logout(HttpServletRequest request) {
        //payload是在网关AuthGlobalFilter中放进去的
        String token = tokenUtils.getToken(request);
        Claims claims = tokenUtils.getClaimsFromToken(token);

        // JWT唯一标识
        String jti = claims.getId();
        // JWT过期时间戳(单位:秒)
        long exp = claims.getExpiration().getTime();

        long currentTimeSeconds = System.currentTimeMillis() / 1000;

        // token还未过期，将该token存入黑名单
        if (exp > currentTimeSeconds) {
            redisTemplate.opsForValue().set(AuthConstants.TOKEN_BLACKLIST_PREFIX + jti,
                    jti, (exp - currentTimeSeconds), TimeUnit.SECONDS);
        }

        return Result.success();
    }
}
